//	Cocoa application for changing FourCC code of avi file
//
//	Author: Jacek Sowinski - dzaku (at) epf.pl
//
//
//	program under GNU GPL License
//

#import "FourCCController.h"


@implementation FourCCController

-(void)awakeFromNib {
	
	//loading FourCC codes from resources
	[self initAnimations];
	NSBundle *bundle = [NSBundle mainBundle];
	fourCCCodes = [[NSMutableArray alloc] initWithContentsOfFile:[bundle pathForResource:@"codes" ofType:@"plist"]];
	[comboDescription addItemsWithObjectValues:fourCCCodes];
	[comboUsed addItemsWithObjectValues:fourCCCodes];
	modified = false;
	fileOpened = false;
	NSNotificationCenter *defaultCenter;
	defaultCenter=[NSNotificationCenter defaultCenter];
	//double click on the view
	[defaultCenter addObserver:self	selector:@selector(boxWasDblClicked:) name:@"boxDblClicked" object:nil];
	// 
	[defaultCenter addObserver:self	selector:@selector(fileWasDropped:) name:@"fileDropped" object:nil];
	}

- (IBAction)getFourCC:(id)sender {
	
	
	
	NSFileHandle *aviFile;
	NSData *aviHeader;
	@try{
		aviFile = [NSFileHandle fileHandleForReadingAtPath:filePath];
		aviHeader = [aviFile readDataOfLength:224];
	    char magic[]={'R','I','F','F'};
		NSData *magicData=[NSData dataWithBytes:magic length:4];
		if ([magicData isEqualToData:aviHeader ])
			NSLog(@"FileOK");
		
		char desc[5];
		char used[5];
		NSRange descRange={0x70,4};
		NSRange usedRange={0xbc,4};
		[aviHeader getBytes:desc range:descRange];	//reading description
		[aviHeader getBytes:used range:usedRange];
		
		codeUsed=[NSString stringWithCString:used	length:4];
		codeDescription=[NSString stringWithCString:desc	length:4];

		if ([comboDescription indexOfItemWithObjectValue:codeDescription]==NSNotFound) 
			[comboDescription insertItemWithObjectValue:codeDescription atIndex:0];
			
		[comboDescription selectItemWithObjectValue:codeDescription];

		
		if ([comboUsed indexOfItemWithObjectValue:codeUsed]==NSNotFound) 
			[comboUsed insertItemWithObjectValue:codeUsed atIndex:0];
		[comboUsed selectItemWithObjectValue:codeUsed];
			
		
		
		[txtFileName setStringValue:[filePath lastPathComponent]];
		[comboUsed setEnabled:YES];
		[comboDescription setEnabled:YES];
		fileOpened = true;
	}
	@catch (NSException *exception) {
		NSLog([exception name]);
		[self displayError:@"Error opening file" :@"Selected movie file can not be opened"]; //TODO: Localization
		[txtFileName setStringValue:@"Drop Movie Here"]; //TODO: Localization
		[comboDescription removeAllItems];
		[comboUsed removeAllItems];
		fileOpened=false;
	}
	@finally {
		if (aviFile!=nil)
		{
			[aviFile closeFile];
		}
	}
}

- (IBAction)setFourCC:(id)sender {
	NSLog(filePath);
	NSData *newDescription;
	NSData *newUsed;

	if ([[comboDescription stringValue] length]==4&&[[comboUsed stringValue] length]==4)
	{
		newDescription = [[NSString stringWithString:[comboDescription stringValue]] dataUsingEncoding:NSASCIIStringEncoding];
		newUsed = [[NSString stringWithString:[comboUsed stringValue]] dataUsingEncoding:NSASCIIStringEncoding];
		NSFileHandle *aviFile;
		@try{
			newDescription = [[comboDescription stringValue] dataUsingEncoding:NSASCIIStringEncoding];
			newUsed = [[comboUsed stringValue] dataUsingEncoding:NSASCIIStringEncoding];
			aviFile = [NSFileHandle fileHandleForWritingAtPath:filePath];
			[aviFile seekToFileOffset:0x70];
			[aviFile writeData:newDescription];
			[aviFile seekToFileOffset:0xbc];
			[aviFile writeData:newUsed];
			[aviFile closeFile];
			[self displayInformation:@"FourCC codes updated succesfully"]; //TODO:Localization
		}
		@catch (NSException *ex) {
			NSLog(@"Exception while saving data");
			NSLog([ex description]);
		}
		@finally {
			if (aviFile!=nil)
			{
				[aviFile closeFile];
			}
		}
	}
	else
	{
		//TODO: localize
		[self displayError:@"Codes must be 4 characters long":@"Incorrect FourCC values"];
	}
}

- (IBAction)showOpenFile:(id)sender
{
	// need to be moved somewhere else to be initialized only once
	fileTypes = [NSArray arrayWithObject:@"avi"];
	openFile = [NSOpenPanel openPanel];
	[openFile setAllowedFileTypes:fileTypes];
	//
	int result;
	if (filePath != nil)
	{
		result = [openFile runModalForDirectory:nil file:	nil types:fileTypes];
	}
	else {
		result = [openFile runModalForDirectory:NSHomeDirectory() file:	nil types: fileTypes];
	}
	if (result == NSOKButton)
	{
		filePath = [[NSString alloc] initWithString:[openFile filename]];
		[self getFourCC:self];
		NSLog([openFile filename]);

	}

};

- (BOOL)application:(NSApplication *)theApplication
           openFile:(NSString *)filename
{
	
	filePath=[[NSString alloc] initWithString:filename];
	[self getFourCC:self];
	return true;
	
	NSLog(filename);

} 
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication {
	return true;
}

- (void)boxWasDblClicked:(NSNotification*)note {
	//function is invoked when double click action is performed on the dropBox
	[self showOpenFile:self];
}

- (void)fileWasDropped:(NSNotification*)note {
	//function is invoked movie file is dropped on the dropbox
	[self showOpenFile:self];
}

- (void) dealloc {
	NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
	[theAnim release];
	[theAnim2 release];
	[[self class] cancelPreviousPerformRequestsWithTarget:self];
	[nc removeObserver:self];
	[super dealloc];
}

- (void)fadeOutMessage
{	
    // Run the animation.
	if ([theAnim isAnimating])
		[theAnim stopAnimation];
	if ([theAnim2 isAnimating])
		[theAnim2 stopAnimation];
	[[self class] cancelPreviousPerformRequestsWithTarget:self];
    [theAnim startAnimation];
	
}
-(void)fadeInMessage{
	if ([theAnim isAnimating])
		[theAnim stopAnimation];
	if ([theAnim2 isAnimating])
		[theAnim2 stopAnimation];
	[[self class] cancelPreviousPerformRequestsWithTarget:self];
	[theAnim2 startAnimation];
	}

- (void)displayInformation:(NSString*)text{
	
	NSImage* macIcon = [[NSWorkspace sharedWorkspace] iconForFileType: NSFileTypeForHFSTypeCode(kAlertNoteIcon)];
	[msgIcon setImage:macIcon];
	[txtMessage setStringValue:text];
	[self fadeInMessage];
	[[self class] cancelPreviousPerformRequestsWithTarget:self];
	[self performSelector:@selector(fadeOutMessage) withObject:nil afterDelay: FADE_OUT_TIME];	
}
- (void)displayError:(NSString*)text :(NSString*)title{
	//NSImage* macIcon = [[NSWorkspace sharedWorkspace] iconForFileType: NSFileTypeForHFSTypeCode(kAlertStopIcon)];
	//[msgIcon setImage:macIcon];
	//[txtMessage setStringValue:text];
	//[[self class] cancelPreviousPerformRequestsWithTarget:self];
	//[self performSelector:@selector(fadeOutMessage) withObject:nil afterDelay: FADE_OUT_TIME];
	NSAlert *alert = [[NSAlert alloc] init];
	[alert addButtonWithTitle:@"OK"];
	[alert setMessageText:title];
	[alert setInformativeText:text];
	[alert setAlertStyle:NSCriticalAlertStyle];
	[alert beginSheetModalForWindow:mainWindow modalDelegate:self didEndSelector:nil contextInfo:nil];
	
	
}

-(void) initAnimations
{
	firstViewDict = [NSMutableDictionary dictionaryWithCapacity:2];
	[firstViewDict setObject:txtMessage forKey:NSViewAnimationTargetKey];
	[firstViewDict setObject:NSViewAnimationFadeOutEffect
					  forKey:NSViewAnimationEffectKey];
	
	secondViewDict = [NSMutableDictionary dictionaryWithCapacity:2];
	[secondViewDict setObject:msgIcon forKey:NSViewAnimationTargetKey];
	[secondViewDict setObject:NSViewAnimationFadeOutEffect
					   forKey:NSViewAnimationEffectKey];
	theAnim = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray
															   arrayWithObjects:firstViewDict,secondViewDict, nil]];
	
    // Set some additional attributes for the animation.
    [theAnim setDuration:1];    // One second.
    [theAnim setAnimationCurve:NSAnimationEaseIn];
	
	firstViewDict2 = [NSMutableDictionary dictionaryWithCapacity:2];
	[firstViewDict2 setObject:txtMessage forKey:NSViewAnimationTargetKey];
	[firstViewDict2 setObject:NSViewAnimationFadeInEffect
					  forKey:NSViewAnimationEffectKey];
	
	secondViewDict2 = [NSMutableDictionary dictionaryWithCapacity:2];
	[secondViewDict2 setObject:msgIcon forKey:NSViewAnimationTargetKey];
	[secondViewDict2 setObject:NSViewAnimationFadeInEffect
					   forKey:NSViewAnimationEffectKey];
	theAnim2 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray
															   arrayWithObjects:firstViewDict2,secondViewDict2, nil]];
	
    // Set some additional attributes for the animation.
    [theAnim2 setDuration:0.1];    // One second.
    [theAnim2 setAnimationCurve:NSAnimationEaseIn];
	
}


@end
